﻿using RabbitMQ.Client;
using System.Collections.Concurrent;
using System.Security.Authentication;

namespace Basic.EventBus.EventBusRabbitMQ
{
    /// <summary>
    /// RabbitMQ连接池
    /// </summary>
    internal class RabbitMQConnections
    {
        public RabbitMQBusBrokerConfig BrokerConfig { get; private set; }
        private ConnectionFactory Factory;
        private ConcurrentQueue<IConnection> ConnectionPool;
        private int ConnectionNumber;

        public RabbitMQConnections(RabbitMQBusBrokerConfig options)
        {
            BrokerConfig = options;
            Factory = new ConnectionFactory
            {
                HostName = BrokerConfig.Host,
                Port = BrokerConfig.Port,
                UserName = BrokerConfig.User,
                Password = BrokerConfig.Passwd,
                VirtualHost = BrokerConfig.VirtualHost ?? RabbitMQBusBrokerConfig.DefaultVirtualHost,
                //Protocol = Protocols.DefaultProtocol,
                AmqpUriSslProtocols = SslProtocols.Tls,
                AutomaticRecoveryEnabled = true, //自动重连
                RequestedFrameMax = RabbitMQBusBrokerConfig.RequestedFrameMax,
                RequestedHeartbeat = TimeSpan.FromSeconds(BrokerConfig.HeartbeatTimeout) //心跳超时时间
            };
            ConnectionPool = new ConcurrentQueue<IConnection>();
            if (options.PoolSize == 0) options.PoolSize = 8;
        }

        public IConnection GetConnection()
        {
            if (ConnectionNumber < BrokerConfig.PoolSize)
            {
                var conn = Factory.CreateConnection();
                Interlocked.Increment(ref ConnectionNumber);
                return conn;
            }

            if (!ConnectionPool.IsEmpty && ConnectionPool.TryDequeue(out IConnection connection))
            {
                return connection;
            }
            return null;
        }

        public void Return(IConnection connection)
        {
            if (connection != null)
                ConnectionPool.Enqueue(connection);
        }

    }
}